package org.apogee.mil.client.factories;

import java.util.ArrayList;
import java.util.HashMap;

import org.apogee.mil.client.services.admin.AdminService;
import org.apogee.mil.client.services.admin.AdminServiceAsync;
import org.apogee.mil.client.services.greeting.GreetingService;
import org.apogee.mil.client.services.greeting.GreetingServiceAsync;
import org.apogee.mil.client.services.login.LoginService;
import org.apogee.mil.client.services.login.LoginServiceAsync;
import org.apogee.mil.client.services.superuser.SuperUserService;
import org.apogee.mil.client.services.superuser.SuperUserServiceAsync;
import org.apogee.mil.client.services.trainee.TraineeService;
import org.apogee.mil.client.services.trainee.TraineeServiceAsync;
import org.apogee.mil.client.services.trainer.TrainerService;
import org.apogee.mil.client.services.trainer.TrainerServiceAsync;
import org.apogee.mil.shared.User;

import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class ServerServiceFactory {

	
	private static HashMap<Integer, TraineeServiceAsync> trainees = new HashMap<Integer, TraineeServiceAsync>();
	private static HashMap<Integer, LoginServiceAsync> login = new HashMap<Integer, LoginServiceAsync>();
	private static HashMap<Integer, AdminServiceAsync> admin = new HashMap<Integer, AdminServiceAsync>();
	private static HashMap<Integer, GreetingServiceAsync> greet = new HashMap<Integer, GreetingServiceAsync>();
	private static HashMap<Integer, TrainerServiceAsync> trainers = new HashMap<Integer, TrainerServiceAsync>();
	private static HashMap<Integer, SuperUserServiceAsync> superUser = new HashMap<Integer, SuperUserServiceAsync>();
	
	private static HashMap<Integer, User> users = new HashMap<Integer, User>();
	
	
	private static ArrayList<Integer> sessions = new ArrayList<Integer>();
	
	private static boolean ok;

	
	public static int createServerService() {
		
		int id = -1;
		
		int random = Random.nextInt(Integer.MAX_VALUE);
		
		while(sessions.contains(random)) {
			random = Random.nextInt(Integer.MAX_VALUE);
		}
		
		id = random;
		
		sessions.add(id);
		
		final GreetingServiceAsync greetService = GWT.create(GreetingService.class);
		greet.put(id, greetService);
							
		return id;
	}
	
	
	public static boolean initializeFactory(int id) {
		
		ok = true;
		
		final LoginServiceAsync loginService = GWT.create(LoginService.class);
		login.put(id, loginService);
		
		login.get(id).initialize(new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				ok = ok & result.booleanValue();
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				ok = ok & false;
			}
		});
		
		
		greet.get(id).initialize(new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				ok = ok & result.booleanValue();
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				ok = ok & false;
				
			}
		});
		
		return ok;
	}
	
	public static boolean initializeFactory(int id, int accessLevel) {
		
		ok = true;
		
		
		final TraineeServiceAsync serverService = GWT.create(TraineeService.class);
		trainees.put(id, serverService);
		
		trainees.get(id).initialize(new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				ok = ok & result.booleanValue();
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				ok = ok & false;
				
			}
		});
	
		if (accessLevel < 3) {
			
			final TrainerServiceAsync trainerService = GWT.create(TrainerService.class);
			trainers.put(id, trainerService);
			
			trainers.get(id).initialize(new AsyncCallback<Boolean>() {
				
				@Override
				public void onSuccess(Boolean result) {
					ok = ok & result.booleanValue();
					
				}
				
				@Override
				public void onFailure(Throwable caught) {
					ok = ok & false;
					
				}
			});
		}
		
		if (accessLevel < 2) {
			final AdminServiceAsync adminService = GWT.create(AdminService.class);
			admin.put(id, adminService);
			
			admin.get(id).initialize(new AsyncCallback<Boolean>() {
				
				@Override
				public void onSuccess(Boolean result) {
					ok = ok & result.booleanValue();
					
				}
				
				@Override
				public void onFailure(Throwable caught) {
					ok = ok & false;
					
				}
			});
		}
		
		
		if (accessLevel < 3) {
			
			final SuperUserServiceAsync superUserService = GWT.create(SuperUserService.class);
			superUser.put(id, superUserService);
			
			superUser.get(id).initialize(new AsyncCallback<Boolean>() {
				
				@Override
				public void onSuccess(Boolean result) {
					ok = ok & result.booleanValue();
					
				}
				
				@Override
				public void onFailure(Throwable caught) {
					ok = ok & false;
					
				}
			});
			
		}
		
		return ok;
		
	}
	
	
	public static TraineeServiceAsync getTraineeService(int id) {
		return trainees.get(id);
	}
	
	public static TraineeServiceAsync getTraineeService(User user) {
		return getTraineeService(user.getSessionId());
	}
	
	public static LoginServiceAsync getLoginService(int id) {
		return login.get(id);
	}
	
	public static AdminServiceAsync getAdminService(int id) {
		return admin.get(id);
	}
	
	public static GreetingServiceAsync getGreetService(int id) {
		return greet.get(id);
	}
	
	public static TrainerServiceAsync getTrainerService(int id) {
		return trainers.get(id);
	}
	
	public static SuperUserServiceAsync getSuperUserService(int id) {
		return superUser.get(id);
	}
	
	public static void addUser(int sessionId, User user) {
		users.put(sessionId, user);
	}
	
	
	public static User getUser(int sessionId) {
		
		User user = users.get(sessionId);
		
		if (user == null) {
			MessageBox.alert("Error", "User is null", null);
		}
		
		return user;
	}
	
	
	public static void close(int id) {
		trainees.get(id).close(new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				
				
			}
		});
		
		login.get(id).close(new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				
			}
		});
		
		admin.get(id).close(new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				
				
			}
		});
		
		trainers.get(id).close(new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				
			}
		});
		
		superUser.get(id).close(new AsyncCallback<Boolean>() {

			@Override
			public void onFailure(Throwable caught) {
				
			}

			@Override
			public void onSuccess(Boolean result) {
				
			}
		});
		
		trainees.remove(id);
		login.remove(id);
		admin.remove(id);
		trainers.remove(id);
		superUser.remove(id);
	}
}
